﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Xml.Linq;
using Nablasoft.Console.Utils;
using TfsUtils.Commands;

namespace TfsUtils.Utils
{
    public static class CommandFactory
    {
        private static Dictionary<String, CommandDef> _commands;

        private static List<Parameter> _commonParameters;
        static CommandFactory()
        {
            _commands = new Dictionary<string, CommandDef>();
            _commonParameters= new List<Parameter>();

            var data = new StreamReader(Assembly.GetExecutingAssembly()
                .GetManifestResourceStream("TfsUtils.CommandDefinition.xml"));
            String global = data.ReadToEnd();
            var commands = XElement.Parse(global);
            var commonParams = from cd in commands.Elements("commonparams")
                               from param in cd.Descendants("parameter")
                                   select param;
            foreach (XElement commonParam in commonParams)
            {
                Object defaultvalue = null;
                if (commonParam.Attribute("default") != null)
                {
                    defaultvalue = commonParam.Attribute("default").Value;
                }
                _commonParameters.Add(new Parameter(
                   (String)commonParam.Attribute("name"),
                   (String)commonParam.Attribute("desc"),
                   defaultvalue));
               
            }

            var commandsDefinitions = from cd in commands.Elements("commanddef")
                                      select cd;
            foreach (XElement element in commandsDefinitions)
            {
                var specificParameters = element.Elements("parameter").Select(p => new Parameter(
                                    (String) p.Attribute("name"),
                                    (String) p.Attribute("desc")));
                CommandDef cd = new CommandDef(_commonParameters.Union(specificParameters).ToList());
                cd.Name = (String) element.Attribute("name");
                cd.ClassName = (String) element.Attribute("class");
                _commands.Add(cd.Name, cd);
            }
        }

        public static ICommand Parse(string[] parameters)
        {
            //first parameter is name of the tool
            //Second parameter is the command
            String commandName = parameters[0];
            //Now find the command in the Elements
            CommandDef cd = _commands[commandName];
            return cd.Create(parameters);
        }
    }
}
